home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / loading / IncrementalLoadADotOut.c < prev    next >
C/C++ Source or Header  |  1990-10-04  |  27KB  |  894 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA 94304
  14.   endcopyright */
  15.  
  16.  
  17. /*
  18.  * IncrementalLoadADotOut.c
  19.  *
  20.  * Incremental loading proc for a.out files.
  21.  * Currently implemented for: sparc.
  22.  *
  23.  * Demers, July 10, 1990 1:33:36 pm PDT
  24.  * Aizawa January 5, 1990 3:09:39 pm PST
  25.  *
  26.  * Note this code presumes some correspondence
  27.  *   between ILSE_xxx and N_xxx typecodes.
  28.  */
  29.  
  30. #ifdef UNIXDEBUG
  31. #   include <stdio.h>
  32. #endif
  33.  
  34. #define RELOC_UNDF_EXT_ONLY    0
  35.  
  36. #include "xr/BasicTypes.h"
  37. #include "xr/IncrementalLoad.h"
  38. #include "xr/IncrementalLoadPrivate.h"
  39. #include "xr/Errno.h"
  40. #include "xr/PZone.h"
  41.  
  42. #include "xr/BldSymX.h"
  43.  
  44. #include <sys/types.h>
  45. #include <string.h>
  46.  
  47. #ifndef N_BADMAG
  48. # include <a.out.h>
  49. #endif
  50.  
  51. #ifndef N_GSYM
  52. # include <stab.h>
  53. #endif
  54.  
  55.  
  56.  
  57. #ifdef sparc
  58. # define RelocInfo    struct reloc_info_sparc
  59. # define MACHTYPE    M_SPARC
  60. #else
  61. --> fix me <--
  62. #endif
  63.  
  64.  
  65. /* file-type-specific temp fields of the il sym tab structure */
  66.  
  67. #define XR_ILAOExec(ilst)    ((struct exec **)(ilst->ilst_fileData))[0]
  68.  
  69. #define XR_ILAOText(ilst)    ((char **)(ilst->ilst_fileData))[1]
  70.  
  71. #define XR_ILAOData(ilst)    ((char **)(ilst->ilst_fileData))[2]
  72.  
  73. #define XR_ILAOTReloc(ilst)    ((RelocInfo **)(ilst->ilst_fileData))[3]
  74.  
  75. #define XR_ILAODReloc(ilst)    ((RelocInfo **)(ilst->ilst_fileData))[4]
  76.  
  77. #define XR_ILAOSymsx(ilst)    ((struct nlistx **)(ilst->ilst_fileData))[5]
  78. #define XR_ILAONSymsx(ilst)    ((unsigned *)(ilst->ilst_fileData))[6]
  79.  
  80. #define XR_ILAOStrings(ilst)    ((char **)(ilst->ilst_fileData))[8]
  81.  
  82. #define ErrRes(ilst,m) { XR_ILSetError(ilst, TRUE, ENOEXEC, (m)); return; }
  83.  
  84. #define CheckRes2(ilst,stmt) if( (ilst)->ilst_result != NIL ) stmt
  85. #define CheckRes(ilst) CheckRes2(ilst,return)
  86.  
  87. #define SetRes2(ilst,fatal,code,msg,stmt) \
  88.     { XR_ILSetError((ilst),(fatal),(code),(msg)); stmt; }
  89.  
  90. #define ROUNDUPWORD(x) \
  91.     ( (((unsigned)(x))+(sizeof(int)-1)) & (~(sizeof(int)-1)) )
  92.  
  93.  
  94. /*
  95.  * I/O
  96.  */
  97.  
  98. static void
  99. XR_ILAOReadExec(ilst)
  100.     XR_ILSymTab ilst;
  101. {
  102.     struct exec *a;
  103.  
  104.     a = (struct exec *)
  105.             XR_PZmalloc( ilst->ilst_zonePerFile, sizeof(struct exec) );
  106.     if( a == NIL ) {
  107.         XR_ILSetError(ilst, TRUE, ENOMEM, "ILAOReadExec out of memory");
  108.         return;
  109.     }
  110.     XR_ILRead(ilst, 0, a, sizeof(struct exec), FALSE);
  111.     CheckRes(ilst);
  112.  
  113.     /* check magic number and cpu type */
  114.     { unsigned m = ilst->ilst_ilfte->ilfte_ilfe.ilfe_fMagic;
  115.         if( N_BADMAG(*a) ) {
  116.             XR_ILSetError(ilst, FALSE, EDOM, "ILAOReadExec file not a.out");
  117.             return;
  118.         }
  119.         if( a->a_machtype != MACHTYPE ) {
  120.             XR_ILSetError(ilst, FALSE, ENOEXEC,
  121.                     "ILAOReadExec file wrong machine type");
  122.             return;
  123.         }
  124.         if( (m != 0) && (a->a_magic != m) ) {
  125.             XR_ILSetError(ilst, FALSE, ENOEXEC,
  126.                     "ILAOReadExec file wrong magic number");
  127.             return;
  128.         }
  129.         ilst->ilst_ilfte->ilfte_ilfe.ilfe_fMagic = a->a_magic;
  130.     }
  131.     /* check to be sure file is not stripped! */
  132.     {
  133.         if( (a->a_syms == 0) && (a->a_trsize == 0)
  134.                 && (a->a_drsize == 0) ) {
  135.             XR_ILSetError(ilst, FALSE, ENOEXEC,
  136.                     "ILAOReadExec stripped file");
  137.             return;
  138.         }
  139.     }
  140.  
  141.     XR_ILAOExec(ilst) = a;
  142. }
  143.  
  144.  
  145. static char *
  146. XR_ILAOSymXAllocProc(clientData, sxd)
  147.     char *clientData;
  148.     XR_SymXData sxd;
  149. {
  150.     XR_ILSymTab ilst = ((XR_ILSymTab)(clientData));
  151.  
  152.     if( sxd->sxd_nsymsx > 0 ) {
  153.         sxd->sxd_symsx = (struct nlistx *) XR_PZmalloc(
  154.             ilst->ilst_zonePerFile, sxd->sxd_nsymsx * sizeof(struct nlistx) );
  155.         if( sxd->sxd_symsx == NIL )
  156.             return "ILAOSymXAllocProc no memory for syms";
  157.     }
  158.     if( sxd->sxd_nstringsx > 0 ) {
  159.         sxd->sxd_stringsx = (char *) XR_PZmalloc(
  160.             ilst->ilst_zonePtrFree, sxd->sxd_nstringsx );
  161.         if( sxd->sxd_stringsx == NIL )
  162.             return "ILAOSymXAllocProc no memory for strings";
  163.     }
  164.     if( sxd->sxd_nstabs > 0 ) {
  165.         sxd->sxd_stabs = (struct dbxstabs *) XR_PZmalloc(
  166.             ilst->ilst_zonePtrFree, sxd->sxd_nstabs * sizeof(struct dbxstabs) );
  167.         if( sxd->sxd_stabs == NIL )
  168.             return "ILAOSymXAllocProc no memory for dbx stabs";
  169.     }
  170.     return NIL;
  171. }
  172.  
  173.  
  174. static void
  175. XR_ILAORelocateSymsX(ilst)
  176.     XR_ILSymTab ilst;
  177. {
  178.     struct nlistx *p, *pLim;
  179.  
  180.     p = XR_ILAOSymsx(ilst);
  181.     pLim = p + XR_ILAONSymsx(ilst);
  182.     while( p < pLim ) {
  183.         if( p->nx_n.n_un.n_strx != 0 ) {
  184.             p->nx_n.n_un.n_name = XR_ILAOStrings(ilst) + p->nx_n.n_un.n_strx;
  185.         }
  186.         p++;
  187.     }
  188. }
  189.  
  190.  
  191. static void
  192. XR_ILAOReadRawSymbolsAndStrings(ilst)
  193.     XR_ILSymTab ilst;
  194. {
  195.     XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
  196.     struct exec *a = XR_ILAOExec(ilst);
  197.     struct XR_SymXDataRep sxd;
  198.     unsigned nRawSyms = 0;
  199.     unsigned rawStringBytes;
  200.     char *bldAns;
  201.     XR_PZone z;
  202.  
  203.     z = XR_PZCreate( TRUE, 0 );
  204.  
  205.     (void) bzero( ((char *)(&sxd)), (sizeof sxd) );
  206.  
  207.     sxd.sxd_hdr = a;
  208.  
  209.     if( a->a_syms == 0 ) {
  210.         sxd.sxd_syms = NIL;
  211.     } else {
  212.         sxd.sxd_syms = (struct nlist *) XR_PZmalloc( z, a->a_syms );
  213.         if( sxd.sxd_syms == NIL ) {
  214.             SetRes2( ilst, TRUE, ENOMEM,
  215.                 "ILAOReadRawSymbolsAndStrings no memory for raw syms",
  216.                 goto CleanUp );
  217.         }
  218.         XR_ILRead(ilst, N_SYMOFF(*a), sxd.sxd_syms, a->a_syms, FALSE);
  219.         CheckRes2(ilst, goto CleanUp);
  220.     }
  221.     XR_ILRead(ilst, N_STROFF(*a), &rawStringBytes,
  222.             (sizeof rawStringBytes), FALSE);
  223.     CheckRes2(ilst, goto CleanUp);
  224.     sxd.sxd_strings = (char *) XR_PZmalloc(z, rawStringBytes );
  225.     if( sxd.sxd_strings == NIL ) {
  226.         SetRes2( ilst, TRUE, ENOMEM,
  227.             "ILAOReadRawSymbolsAndStrings no memory for raw strings",
  228.             goto CleanUp );
  229.     }
  230.     XR_ILRead(ilst, N_STROFF(*a), sxd.sxd_strings, rawStringBytes, FALSE);
  231.     CheckRes2(ilst, goto CleanUp);
  232.     
  233.  
  234.     bldAns = XR_BldSymX( &sxd, XR_ILAOSymXAllocProc, ((char *)(ilst)), FALSE );
  235.     if( bldAns != NIL ) {
  236.         SetRes2( ilst, FALSE, ENOEXEC, 
  237.             "ILAOReadRawSymbolsAndStrings BldSymX failed",
  238.             goto CleanUp );
  239.     }
  240.     XR_ILAONSymsx(ilst) = sxd.sxd_nsymsx;
  241.     XR_ILAOSymsx(ilst) = sxd.sxd_symsx;
  242.     XR_ILAOStrings(ilst) = sxd.sxd_stringsx;
  243.     XR_ILAORelocateSymsX(ilst);
  244.     ilfe->ilfe_rdrDataBytes = sxd.sxd_nstabs * sizeof(struct dbxstabs);
  245.     ilfe->ilfe_rdrData = (caddr_t) sxd.sxd_stabs;
  246.  
  247.   CleanUp:
  248.  
  249.     XR_PZrevert( z, XR_PZ_FREE_ALL );
  250. }
  251.  
  252.  
  253. #ifdef UNDEFINED
  254. static void
  255. XR_ILAOReadSymbolsAndStrings(ilst)
  256.     XR_ILSymTab ilst;
  257. {
  258.     struct hdrx hx;
  259.     unsigned pos, hxpos;
  260.     unsigned stringBytes, nSymsx;
  261.     XR_Pointer dbxSTABs;
  262.     XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
  263.     struct exec *a = XR_ILAOExec(ilst);
  264.  
  265.     pos = N_STROFF(*a);
  266.     XR_ILRead(ilst, pos, &stringBytes, (sizeof stringBytes), FALSE);
  267.     CheckRes(ilst);
  268.     hxpos = ROUNDUPWORD(pos + stringBytes);
  269.     XR_ILRead(ilst, hxpos, &hx, (sizeof hx), FALSE);
  270.     CheckRes2(ilst, goto ReadRaw);
  271.     if( !HDRX_OK(hx) ) goto ReadRaw;
  272.  
  273.     XR_ILAOSymsx(ilst) = NIL;
  274.     if( hx.hx_symBytes > 0 ) {
  275.         XR_ILAOSymsx(ilst) = (struct nlistx *)
  276.                 XR_PZmalloc( ilst->ilst_zonePerFile, hx.hx_symBytes );
  277.         if( XR_ILAOSymsx(ilst) == NIL ) {
  278.             SetRes2(ilst, TRUE, ENOMEM,
  279.                 "ILAOReadSymbolsAndStrings no memory for syms",
  280.                 return );
  281.         }
  282.         pos = hxpos + NX_SECTRELOFF(hx, HDRX_SYM_SECTION);
  283.         XR_ILRead(ilst, pos, XR_ILAOSymsx(ilst), hx.hx_symBytes, FALSE);
  284.         CheckRes2(ilst, goto ReadRaw);
  285.     }
  286.  
  287.     XR_ILAONSymsx(ilst) = hx.hx_symBytes / sizeof(struct nlistx);
  288.     XR_ILAOStrings(ilst) = (char *)
  289.             XR_PZmalloc( ilst->ilst_zonePtrFree, hx.hx_strBytes );
  290.     if( XR_ILAOStrings(ilst) == NIL ) {
  291.         SetRes2(ilst, TRUE, ENOMEM,
  292.             "ILAOReadSymbolsAndStrings no memory for strings",
  293.             return );
  294.     }
  295.     pos = hxpos + NX_SECTRELOFF(hx, HDRX_STR_SECTION);
  296.     XR_ILRead(ilst, pos, XR_ILAOStrings(ilst), hx.hx_strBytes, FALSE);
  297.     CheckRes2(ilst, goto ReadRaw);
  298.     XR_ILAORelocateSymsX(ilst);
  299.  
  300.     if( hx.hx_dbxSTABBytes == 0 ) goto NoDBXSTABs;
  301.     dbxSTABs = (XR_Pointer)
  302.             XR_PZmalloc( ilst->ilst_zonePtrFree, hx.hx_dbxSTABBytes );
  303.     if( dbxSTABs == NIL ) {
  304.         SetRes2(ilst, TRUE, ENOMEM,
  305.             "ILAOReadSymbolsAndStrings no memory for dbx stabs",
  306.             return );
  307.     }
  308.     pos = hxpos + NX_SECTRELOFF(hx, HDRX_DBXSTAB_SECTION);
  309.     XR_ILRead(ilst, pos, ((char *)(dbxSTABs)), hx.hx_dbxSTABBytes, FALSE);
  310.     CheckRes2(ilst, goto NoDBXSTABs);
  311.     ilfe->ilfe_rdrDataBytes = hx.hx_dbxSTABBytes;
  312.     ilfe->ilfe_rdrData = (caddr_t) dbxSTABs;
  313.     return;
  314.  
  315.   NoDBXSTABs:
  316.     ilfe->ilfe_rdrDataBytes = 0;
  317.     ilfe->ilfe_rdrData = NIL;
  318.     return;
  319.  
  320.   ReadRaw:
  321.     ilst->ilst_result = NIL;
  322.     XR_ILAOSymsx(ilst) = NIL;
  323.     XR_ILAONSymsx(ilst) = 0;
  324.     XR_ILAOStrings(ilst) = NIL;
  325.     XR_ILAOReadRawSymbolsAndStrings(ilst);
  326.     return;
  327. }
  328. #else
  329. static int
  330. XR_ILAOXLSeekProc(pos, whence, ilst)
  331.     int pos;
  332.     int whence;
  333.     XR_ILSymTab ilst;
  334. {
  335.     static int buf;
  336.  
  337.     if( whence != L_SET ) {
  338. XR_ConsoleMsg("XR_ILAOXLSeekProc whence botch %d\n", whence);
  339.         return(-1);
  340.     }
  341.     XR_ILRead(ilst, pos, buf, 0, FALSE);
  342.     CheckRes2(ilst, return(-1));
  343. }
  344.  
  345. static int
  346. XR_ILAOXReadProc(buf, nbytes, ilst)
  347.     char *buf;
  348.     int nbytes;
  349.     XR_ILSymTab ilst;
  350. {
  351.     XR_ILRead(ilst, (-1), buf, nbytes, FALSE);
  352.     CheckRes2(ilst, return(-1));
  353. }
  354.  
  355.  
  356.  
  357. static void
  358. XR_ILAOReadSymbolsAndStrings(ilst)
  359.     XR_ILSymTab ilst;
  360. {
  361.     int ans;
  362.     int subsecPos, subsecBytes;
  363.     int stringsxPos, stringsxBytes;
  364.     int nlistxPos, nlistxBytes;
  365.     int stabsPos, stabsBytes;
  366.     XR_Pointer dbxSTABs;
  367.     XR_ILFileEntry ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
  368.  
  369.     ans = XR_FindExtraSubsec(
  370.             XR_ILAOXLSeekProc, XR_ILAOXReadProc, ilst,
  371.             ILSymsXSubsecName, &subsecPos, &subsecBytes );
  372.     if( (ans < 0) || (subsecPos == 0) ) goto ReadRaw;
  373.     stringsxPos = subsecPos;
  374.     XR_ILRead(ilst, stringsxPos, &stringsxBytes, (sizeof stringsxBytes), FALSE);
  375.     CheckRes2(ilst, goto ReadRaw);
  376.     stringsxPos += (sizeof stringsxBytes);
  377.     stringsxBytes -= (sizeof stringsxBytes);
  378.     nlistxPos = ROUNDUPWORD(stringsxPos + stringsxBytes);
  379.     XR_ILRead(ilst, nlistxPos, nlistxBytes, (sizeof nlistxBytes), FALSE);
  380.     CheckRes2(ilst, goto ReadRaw);
  381.     nlistxPos += (sizeof nlistxBytes);
  382.     nlistxBytes -= (sizeof nlistxBytes);
  383.     XR_ILAOSymsx(ilst) = NIL;
  384.     if( nlistxBytes > 0 ) {
  385.         XR_ILAOSymsx(ilst) = (struct nlistx *)
  386.                 XR_PZmalloc( ilst->ilst_zonePerFile, nlistxBytes );
  387.         if( XR_ILAOSymsx(ilst) == NIL ) {
  388.             SetRes2(ilst, TRUE, ENOMEM,
  389.                 "ILAOReadSymbolsAndStrings no memory for syms",
  390.                 return );
  391.         }
  392.         XR_ILRead(ilst, nlistxPos, XR_ILAOSymsx(ilst), nlistxBytes, FALSE);
  393.         CheckRes2(ilst, goto ReadRaw);
  394.     }
  395.  
  396.     XR_ILAONSymsx(ilst) = nlistxBytes / sizeof(struct nlistx);
  397.     XR_ILAOStrings(ilst) = (char *)
  398.             XR_PZmalloc( ilst->ilst_zonePtrFree, stringsxBytes );
  399.     if( XR_ILAOStrings(ilst) == NIL ) {
  400.         SetRes2(ilst, TRUE, ENOMEM,
  401.             "ILAOReadSymbolsAndStrings no memory for strings",
  402.             return );
  403.     }
  404.     XR_ILRead(ilst, stringsxPos, XR_ILAOStrings(ilst), stringsxBytes, FALSE);
  405.     CheckRes2(ilst, goto ReadRaw);
  406.     XR_ILAORelocateSymsX(ilst);
  407.  
  408.     ans = XR_FindExtraSubsec(
  409.             XR_ILAOXLSeekProc, XR_ILAOXReadProc, ilst,
  410.             STABGrpsXSubsecName, &stabsPos, &stabsBytes );
  411.     if( (ans < 0) || (stabsPos == 0) ) goto NoDBXSTABs;
  412.     dbxSTABs = (XR_Pointer)
  413.             XR_PZmalloc( ilst->ilst_zonePtrFree, stabsBytes );
  414.     if( dbxSTABs == NIL ) {
  415.         SetRes2(ilst, TRUE, ENOMEM,
  416.             "ILAOReadSymbolsAndStrings no memory for dbx stabs",
  417.             return );
  418.     }
  419.     XR_ILRead(ilst, stabsPos, ((char *)(dbxSTABs)), stabsBytes, FALSE);
  420.     CheckRes2(ilst, goto NoDBXSTABs);
  421.     ilfe->ilfe_rdrDataBytes = stabsBytes;
  422.     ilfe->ilfe_rdrData = (caddr_t) dbxSTABs;
  423.     return;
  424.  
  425.   NoDBXSTABs:
  426.     ilfe->ilfe_rdrDataBytes = 0;
  427.     ilfe->ilfe_rdrData = NIL;
  428.     return;
  429.  
  430.   ReadRaw:
  431.     ilst->ilst_result = NIL;
  432.     XR_ILAOSymsx(ilst) = NIL;
  433.     XR_ILAONSymsx(ilst) = 0;
  434.     XR_ILAOStrings(ilst) = NIL;
  435.     XR_ILAOReadRawSymbolsAndStrings(ilst);
  436.     return;
  437. }
  438. #endif
  439.  
  440. static struct nlistx *
  441. XR_ILAOGetSymxFromIndex(ilst, index)
  442.     XR_ILSymTab ilst;
  443.     unsigned index;
  444. {
  445.     int l, r, m;
  446.     struct nlistx *symsx, *pm;
  447.  
  448.     symsx = XR_ILAOSymsx(ilst);
  449.     l = 0;
  450.     r = ((int)(XR_ILAONSymsx(ilst))) - 1;
  451.     while( l <= r ) {
  452.         m = (l + r) / 2;
  453.         pm = symsx + m;
  454.         if( pm->nx_x == index ) return pm;
  455.         else if( pm->nx_x < index ) l = m + 1;
  456.         else /* pm->nx_x > index */ r = m - 1;
  457.     }
  458.     return NIL;
  459. }
  460.  
  461.  
  462. static void
  463. XR_ILAOAllocSegments(ilst)
  464.     XR_ILSymTab ilst;
  465. {
  466.     struct exec *a = XR_ILAOExec(ilst);
  467.  
  468.     XR_ILAllocSegments( ilst, a->a_text, a->a_data, a->a_bss );
  469.     CheckRes(ilst);
  470. }
  471.  
  472.  
  473.  
  474. static void
  475. XR_ILAOReadSegments(ilst)
  476.     XR_ILSymTab ilst;
  477. {
  478.     XR_ILFileTabEntry ilfte = ilst->ilst_ilfte;
  479.     struct exec *a = XR_ILAOExec(ilst);
  480.  
  481.     if( ilfte->ilfte_ilfe.ilfe_tBytes > 0 ) {
  482.         XR_ILRead( ilst, N_TXTOFF(*a),
  483.                 ilfte->ilfte_ilfe.ilfe_tAddr,
  484.                 ilfte->ilfte_ilfe.ilfe_tBytes, FALSE );
  485.         CheckRes(ilst);
  486.     }
  487.  
  488.     if( ilfte->ilfte_ilfe.ilfe_dBytes > 0 ) {
  489.         XR_ILRead(ilst, N_DATOFF(*a),
  490.             ilfte->ilfte_ilfe.ilfe_dAddr,
  491.             ilfte->ilfte_ilfe.ilfe_dBytes, FALSE);
  492.         CheckRes(ilst);
  493.     }
  494. }
  495.  
  496.  
  497. /*
  498.  * Create an external MODULE symbol for this file.
  499.  * Put all external, text and MODULE symbols into XR_ilSymTab.
  500.  * Set n_un.n_name field to point to entry in XR_ilSymTab.
  501.  * Fix up values of other symbols (not really necessary).
  502.  */
  503.  
  504. static void
  505. XR_ILAOProcessSymbols(ilst)
  506.     XR_ILSymTab ilst;
  507. {
  508.     XR_ILFileEntry ilfe;
  509.     struct exec *a;
  510.     struct nlistx *px, *pxLim;
  511.     unsigned tReloc, dReloc, bReloc;
  512.     XR_ILSymTabEntry prevModuleEntry, thisModuleEntry, thisPatchEntry;
  513.     char *ilfeShortName;
  514. #   if (_FN != (N_FN & N_TYPE))
  515.         /* this is a pre-4.1 compilation (delete this after 4.1) */
  516.         int pre4Dot1ErrMsgCnt = 0;
  517. #   endif
  518.  
  519. #   ifdef UNIXDEBUG
  520.         printf("ILAOProcessSymbols() nSymsx %d\n", XR_ILAONSymsx(ilst));
  521. #   endif
  522.  
  523.     ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
  524.     a = XR_ILAOExec(ilst);
  525.  
  526.     tReloc = (unsigned)(ilfe->ilfe_tAddr);
  527.     dReloc = (unsigned)(ilfe->ilfe_dAddr - a->a_text);
  528.     bReloc = (unsigned)(ilfe->ilfe_bAddr - a->a_text - a->a_data);
  529.  
  530.     if( (ilfeShortName = strrchr(ilfe->ilfe_fName, '/')) != NIL ) {
  531.         ilfeShortName += 1;
  532.     } else {
  533.         ilfeShortName = ilfe->ilfe_fName;
  534.     }
  535.  
  536.     /* Create MODULE|EXT symbol for the entire file ... */
  537.     thisModuleEntry = XR_ILSetSymDefined(
  538.         ilst,
  539.         ilfeShortName, XR_ILHashFromSym(ilfeShortName),
  540.         (ILSE_MODULE|ILSE_EXT), tReloc);
  541.     if( thisModuleEntry == NIL ) return;
  542.     thisModuleEntry->ilste_ilse.ilse_size = a->a_text;
  543.  
  544.     /* Create PATCH|EXT symbol if there is a patch area ... */
  545.     if( ilfe->ilfe_pBytes > 0 ) {
  546.         thisPatchEntry = XR_ILSetSymDefined(
  547.             ilst,
  548.             ilfeShortName, XR_ILHashFromSym(ilfeShortName),
  549.             (ILSE_PATCH|ILSE_EXT), ilfe->ilfe_pAddr);
  550.         if( thisPatchEntry == NIL ) return;
  551.         thisPatchEntry->ilste_ilse.ilse_size = ilfe->ilfe_pBytes;
  552.     }
  553.  
  554.     /* Process the symbol table ... */
  555.     px = XR_ILAOSymsx(ilst);
  556.     pxLim = px + XR_ILAONSymsx(ilst);
  557.     prevModuleEntry = NIL;
  558.     while( px < pxLim ) {
  559.         char *sym;
  560.         unsigned hash;
  561.  
  562.         sym = px->nx_n.n_un.n_name;
  563.         hash = XR_ILHashFromSym(sym);
  564.         switch( px->nx_n.n_type & N_TYPE ) {
  565.             case (N_FN & N_TYPE):
  566.                 /* "&N_TYPE" fixes bug in pre-4.1 <sun4/a.out.h> */
  567.                 /* Delete the following after 4.1 */
  568. #               if (N_FN == (N_FN & N_TYPE))
  569.                     /* this is 4.1 or later */
  570.                     break;
  571. #               else
  572.                     /* this is pre-4.1 */
  573.                     if( pre4Dot1ErrMsgCnt == 0 ) {
  574.                         XR_ConsoleMsg( "ILADotOut: sym type 0x%x\n",
  575.                                 px->nx_n.n_type & N_TYPE );
  576.                         pre4Dot1ErrMsgCnt += 1;
  577.                     }
  578.                     /* fall thru and treat it like N_MODULE */
  579. #               endif
  580.             case N_MODULE:
  581.                 thisModuleEntry = XR_ILSetSymDefined(
  582.                         ilst, sym, hash, ILSE_MODULE,
  583.                         px->nx_n.n_value + tReloc);
  584.                 if( thisModuleEntry == NIL ) return;
  585.                 thisModuleEntry->ilste_ilse.ilse_size = (
  586.                     tReloc + ilfe->ilfe_tBytes
  587.                         - thisModuleEntry->ilste_ilse.ilse_value
  588.                     /* upper bound -- updated just below */
  589.                 );
  590.                 if( prevModuleEntry != NIL ) {
  591.                     prevModuleEntry->ilste_ilse.ilse_size = (
  592.                         thisModuleEntry->ilste_ilse.ilse_value
  593.                             - prevModuleEntry->ilste_ilse.ilse_value
  594.                     );
  595.                 }
  596.                 prevModuleEntry = thisModuleEntry;
  597.                 px->nx_n.n_type = N_TEXT;
  598.                 /* FALL THRU to N_TEXT case ... */
  599.             case N_TEXT:
  600.                 px->nx_n.n_value += tReloc;
  601.                 px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
  602.                         ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
  603.                 if( px->nx_n.n_un.n_name == NIL ) return;
  604.                 break;
  605.             case N_DATA:
  606.                 px->nx_n.n_value += dReloc;
  607.                 if( px->nx_n.n_type & N_EXT ) {
  608.                     px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
  609.                             ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
  610.                     if( px->nx_n.n_un.n_name == NIL ) return;
  611.                 }
  612.                 break;
  613.             case N_BSS:
  614.                 px->nx_n.n_value += bReloc;
  615.                 if( px->nx_n.n_type & N_EXT ) {
  616.                     px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
  617.                             ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
  618.                     if( px->nx_n.n_un.n_name == NIL ) return;
  619.                 }
  620.                 break;
  621.             case N_ABS:
  622.                 if( px->nx_n.n_type & N_EXT ) {
  623.                     px->nx_n.n_un.n_name = (char *) XR_ILSetSymDefined(
  624.                             ilst, sym, hash, px->nx_n.n_type, px->nx_n.n_value);
  625.                     if( px->nx_n.n_un.n_name == NIL ) return;
  626.                 }
  627.                 break;
  628.             case N_UNDF:
  629.                 if( !(px->nx_n.n_type & N_EXT) ) {
  630.                     ErrRes(ilst, "undefined internal symbol found");
  631.                 }
  632.                 if( px->nx_n.n_value != 0 ) {
  633.                     px->nx_n.n_un.n_name = (char *) XR_ILSetSymCommon(
  634.                             ilst, sym, hash, px->nx_n.n_value);
  635.                     if( px->nx_n.n_un.n_name == NIL ) return;
  636.                 } else {
  637.                     px->nx_n.n_un.n_name = (char *) XR_ILSetSymReferenced(
  638.                             ilst, sym, hash);
  639.                     if( px->nx_n.n_un.n_name == NIL ) return;
  640.                 }
  641.                 break;
  642.             default:
  643.                 ErrRes( ilst, "unknown symbol type found" );
  644.         }
  645.         px++;
  646.     }
  647. }
  648.  
  649. static void
  650. XR_ILAOReadRelocationInfo(ilst)
  651.     XR_ILSymTab ilst;
  652. {
  653.     struct exec *a = XR_ILAOExec(ilst);
  654.  
  655.     XR_ILAOTReloc(ilst) = NIL;
  656.     if( a->a_trsize > 0 ) {
  657.         XR_ILAOTReloc(ilst) = (RelocInfo *)
  658.                 XR_PZmalloc(ilst->ilst_zonePerFile, a->a_trsize);
  659.         if( XR_ILAOTReloc(ilst) == NIL ) {
  660.             SetRes2(ilst, TRUE, ENOMEM,
  661.                 "ILAOReadRelocationInfo no memory for text reloc",
  662.                 return );
  663.         }
  664.         XR_ILRead( ilst, N_TRELOFF(*a),
  665.                 XR_ILAOTReloc(ilst), a->a_trsize, TRUE );
  666.         CheckRes(ilst);
  667.     }
  668.     XR_ILAODReloc(ilst) = NIL;
  669.     if( a->a_drsize > 0 ) {
  670.         XR_ILAODReloc(ilst) = (RelocInfo *)
  671.                 XR_PZmalloc(ilst->ilst_zonePerFile, a->a_drsize);
  672.         if( XR_ILAODReloc(ilst) == NIL ) {
  673.             SetRes2(ilst, TRUE, ENOMEM,
  674.                 "ILAOReadRelocationInfo no memory for data reloc",
  675.                 return );
  676.         }
  677.         XR_ILRead( ilst, N_DRELOFF(*a),
  678.                 XR_ILAODReloc(ilst), a->a_drsize, TRUE );
  679.         CheckRes(ilst);
  680.     }
  681. }
  682.  
  683.  
  684. #ifdef sparc
  685. static void
  686. XR_ILAORelocateProc(addr, relocType, addend, val)
  687.     char *addr;
  688.     unsigned relocType;
  689.     long addend;
  690.     unsigned val;
  691. {
  692.     long relocVal;
  693. #   define MemInsert(p,v,shift,mask) *((long *)(p)) = \
  694.         ( (*((long *)(p)) & (mask)) | ((((long)(v)) >> (shift)) & (~(mask))) )
  695.  
  696.     relocVal = addend + val;
  697.     switch( relocType ) {
  698.         case RELOC_8:
  699.         case RELOC_DISP8:
  700.             *((char *)(addr)) = relocVal;
  701.             break;
  702.         case RELOC_16:
  703.         case RELOC_DISP16:
  704.             *((short *)(addr)) = relocVal;
  705.             break;
  706.         case RELOC_32:
  707.         case RELOC_DISP32:
  708.             *((long *)(addr)) = relocVal;
  709.             break;
  710.         case RELOC_WDISP30:
  711.             MemInsert(addr,relocVal,2,0xc0000000);
  712.             break;
  713.         case RELOC_WDISP22:
  714.             MemInsert(addr,relocVal,2,0xffc00000);
  715.             break;
  716.         case RELOC_HI22:
  717.             MemInsert(addr,relocVal,10,0xffc00000);
  718.             break;
  719.         case RELOC_22:
  720.             MemInsert(addr,relocVal,0,0xffc00000);
  721.             break;
  722.         case RELOC_13:
  723.             MemInsert(addr,relocVal,0,0xffffe000);
  724.             break;
  725.         case RELOC_LO10:
  726.             MemInsert(addr,relocVal,0,0xfffffc00);
  727.             break;
  728.         case RELOC_SFA_BASE:
  729.             ErrRes(XR_ilSymTab, "reloc RELOC_SFA_BASE?" );
  730.         case RELOC_SFA_OFF13:
  731.             ErrRes(XR_ilSymTab, "reloc RELOC_SFA_OFF13?" );
  732.         case RELOC_SEGOFF16:
  733.             ErrRes(XR_ilSymTab, "reloc RELOC_SEGOFF16?" );
  734.         default:
  735.             ErrRes(XR_ilSymTab, "unknown reloc" );
  736.     }
  737. }
  738.  
  739.  
  740. static void
  741. XR_ILAORelocateInner(ilst, seg)
  742.     XR_ILSymTab ilst;
  743.     unsigned seg;
  744. {
  745.     RelocInfo *rp, *rpLim;
  746.     unsigned tReloc, dReloc, bReloc, segReloc, segBase;
  747.     char *addr;
  748.     unsigned addend;
  749.     struct exec *a;
  750.     struct nlistx *nxp;
  751.     XR_ILFileEntry ilfe;
  752.     XR_ILSymTabEntry ilste;
  753.  
  754.     ilfe = &(ilst->ilst_ilfte->ilfte_ilfe);
  755.     a = XR_ILAOExec(ilst);
  756.  
  757.     tReloc = (unsigned)(ilfe->ilfe_tAddr);
  758.     dReloc = (unsigned)(ilfe->ilfe_dAddr - a->a_text);
  759.     bReloc = (unsigned)(ilfe->ilfe_bAddr - a->a_text - a->a_data);
  760.     switch(seg) {
  761.         case N_TEXT:
  762.             rp = XR_ILAOTReloc(ilst);
  763.             rpLim = (RelocInfo *)( ((char *)(rp)) + a->a_trsize );
  764.             segBase = (unsigned)(ilfe->ilfe_tAddr);
  765.             segReloc = tReloc;
  766.             break;
  767.         case N_DATA:
  768.             rp = XR_ILAODReloc(ilst);
  769.             rpLim = (RelocInfo *)( ((char *)(rp)) + a->a_drsize );
  770.             segBase = (unsigned)(ilfe->ilfe_dAddr);
  771.             segReloc = dReloc;
  772.             break;
  773.         default:
  774.             ErrRes(ilst, "internal error (ILAORelocateInner)" );
  775.     }
  776.  
  777.     for( ; rp < rpLim; rp++ ) {
  778.         addr = (char *)(segBase + rp->r_address);
  779.         addend = rp->r_addend;
  780.         switch( rp->r_type ) {
  781.             case RELOC_DISP8:
  782.             case RELOC_DISP16:
  783.             case RELOC_DISP32:
  784.             case RELOC_WDISP30:
  785.             case RELOC_WDISP22:
  786.                 addend -= segReloc;
  787.                 break;
  788.             default:
  789.                 break;
  790.         }
  791.         if( rp->r_extern ) {            
  792.             nxp = XR_ILAOGetSymxFromIndex(ilst, rp->r_index);
  793.             XR_ILAssert( (nxp != NIL), "ILAORelocateInner a0" );
  794. #           if RELOC_UNDF_EXT_ONLY
  795.                 if( nxp->nx_n.n_type != (N_UNDF|N_EXT) ) {
  796.                     ErrRes(ilst, "ILAORelocateInner: reloc not undef extern");
  797.                 }
  798. #           endif
  799.             ilste = (XR_ILSymTabEntry)(nxp->nx_n.n_un.n_name);
  800.             XR_ILRelocate(ilst, ilste, XR_ILAORelocateProc,
  801.                     addr, rp->r_type, addend);
  802.             CheckRes(ilst);
  803.         } else {
  804.             switch( rp->r_index ) {
  805.                 case N_TEXT:
  806.                     addend += tReloc;
  807.                     break;
  808.                 case N_DATA:
  809.                     addend += dReloc;
  810.                     break;
  811.                 case N_BSS:
  812.                     addend += bReloc;
  813.                     break;
  814.                 case N_ABS:
  815.                     /* This does happen ... but does it make sense? */
  816.                     break;
  817.                 default:
  818.                     ErrRes(ilst, "ILAORelocateInner: reloc bad seg");
  819.             }
  820.             XR_ILAORelocateProc(addr, rp->r_type, addend, 0);
  821.             CheckRes(ilst);
  822.         }
  823.     }
  824. }
  825. #else
  826. --> fix me for this (non-sparc) architecture <--
  827. #endif
  828.  
  829.  
  830. static void
  831. XR_ILAORelocate(ilst)
  832.     XR_ILSymTab ilst;
  833. {
  834.     XR_ILAORelocateInner(ilst, N_TEXT);
  835.     CheckRes(ilst);
  836.     XR_ILAORelocateInner(ilst, N_DATA);
  837.     CheckRes(ilst);
  838. }
  839.  
  840.  
  841. #define CALL(f) { XR_/**/f(ilst); CheckRes(ilst); }
  842.  
  843. static void
  844. XR_IncrementalLoadADotOut(ilst)
  845.     XR_ILSymTab ilst;
  846. {
  847.     XR_ILOp op = ilst->ilst_opArg;
  848.  
  849.     switch( op ) {
  850.         case ilOpInternalize:
  851.         case ilOpLoad:
  852.             CALL(ILGetOpenFile);
  853.             CALL(ILAOReadExec);
  854.             CALL(ILAOAllocSegments);
  855.             if( op == ilOpLoad ) CALL(ILAOReadSegments);
  856.             CALL(ILAOReadSymbolsAndStrings);
  857.             CALL(ILAOProcessSymbols);
  858.             if( op == ilOpLoad ) CALL(ILAOReadRelocationInfo);
  859.             if( op == ilOpLoad ) CALL(ILAORelocate);
  860.             break;
  861.         case ilOpCommit:
  862.             break;
  863.         case ilOpAbort:
  864.             break;
  865.         default:
  866.             XR_Panic("IncrementalLoadADotOut bad op");
  867.     }
  868. }
  869.  
  870.  
  871. #undef CALL
  872.  
  873.  
  874. static unsigned XR_ILAOMagics[] = { OMAGIC, NMAGIC, ZMAGIC };
  875. static unsigned XR_ILAONMagics =
  876.         (sizeof XR_ILAOMagics)/(sizeof XR_ILAOMagics[0]);
  877.  
  878. void
  879. XR_run_IncrementalLoadADotOut()
  880. {
  881.     XR_RegisterIncrementalLoadProc(
  882.         XR_IncrementalLoadADotOut, NIL, XR_ILAOMagics, XR_ILAONMagics
  883.     );
  884. }
  885.  
  886. void
  887. XR_run_IncrementalLoadDEFAULT()
  888. {
  889.     XR_RegisterIncrementalLoadProc(
  890.         XR_IncrementalLoadADotOut, NIL, XR_ILAONMagics, XR_ILAOMagics
  891.     );
  892. }
  893.  
  894.